package org.example.booksmanagementsystem.service;

import lombok.extern.slf4j.Slf4j;
import org.example.booksmanagementsystem.enums.BookInfoStatusEnum;
import org.example.booksmanagementsystem.mapper.SpecialDealNormalMapper;
import org.example.booksmanagementsystem.model.BookInfo;
import org.example.booksmanagementsystem.model.PageRequest;
import org.example.booksmanagementsystem.model.PageResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Slf4j
@Service
public class SpecialDealNormalService {
    @Autowired
    private SpecialDealNormalMapper specialDealNormalMapper;

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;


    public PageResult<BookInfo> getSpecialBookListByPage(PageRequest pageRequest) {
        if(pageRequest==null){
            return null;
        }

        //获取表中数据的总数
        Integer count = getAllBookInfoFromRedis().size();

        //获取该页的数据
        List<BookInfo> bookInfoList = getRequestPage(pageRequest);


        //根据status 修改 statusCN
        for(BookInfo it : bookInfoList){
            // 使用枚举类设置图书的状态
            it.setStatusCN(BookInfoStatusEnum.getNameByCode(it.getStatus()).getName());
        }

        // 创建PageResult对象返回给Controller
        return new PageResult<BookInfo>(count,bookInfoList,pageRequest);

    }

    // 根据RequestPage获取数据
    public List<BookInfo> getRequestPage(PageRequest pageRequest){

        // 获取redis数据
        List<BookInfo> bookInfoList = getAllBookInfoFromRedis();

        // 总的数据的个数
        Integer size = bookInfoList.size() - 1;

        if(pageRequest.getOffset()+9 >size){
            bookInfoList.subList(pageRequest.getOffset(),size);
            return bookInfoList;
        }

        bookInfoList.subList(pageRequest.getOffset(),pageRequest.getOffset()+9);

        return bookInfoList;
    }

    // 从Redis中取出所有bookInfo
    public List<BookInfo> getAllBookInfoFromRedis() {
        List<BookInfo> resultList = new ArrayList<>();

        //从Redis中取出所有bookInfoId:前缀的数据

        // 1：获取所有以"bookInfoId:"开头的键
        String keyPattern = "bookInfoId:*";
        Set<String> keys = redisTemplate.keys(keyPattern);


        // 2：遍历键，逐个获取对应的值
        for (String key : keys) {
            BookInfo value = (BookInfo)redisTemplate.opsForValue().get(key);

            // 放入list中
            if(value.getStatus().equals(0)) {
                continue;
            }

            resultList.add(value);
        }

        return resultList;
    }

    //特价专区中购买商品
    public boolean buy(Integer bookId,Integer userId){
        /*
        * 1.检查redis有没有库存
        * 2.减redis中的库存
        * 3.看特价购物车有没买过
        * 4.添加到特价购物车
        *
        * */

        BookInfo bookInfo = null;

        // 找购买的book

        // 1：获取所有以"bookInfoId:"开头的键
        String keyPattern = "bookInfoId:*";
        Set<String> keys = redisTemplate.keys(keyPattern);

        // 2：遍历键，逐个获取对应的值
        for (String key : keys) {
            BookInfo value = (BookInfo)redisTemplate.opsForValue().get(key);

            //找到购买的book
            if(bookId.equals(value.getId())){

                //检查有没有库存
                if(value.getCount().equals(0) || value.getStatus().equals(1)
                        ||value.getStatus().equals(2) || value.getStatus().equals(0)){
                    log.info("库存不足或不可特价购买，特价商品购买失败");
                    return false;
                }

                bookInfo = value;

                // 库存 -1
                bookInfo.setCount(bookInfo.getCount()-1);

                //更新到redis
                redisTemplate.opsForValue().set(key,bookInfo);

                break;

            }


        }

        // 用户是否购买过
        BookInfo bookInfoFromMysql = specialDealNormalMapper.queryBookInfoByNormalId(bookId,userId);
        if(bookInfoFromMysql==null){
            //第一次购买，直接插入
            specialDealNormalMapper.insertUserBookInfoTable(userId,bookInfo);
        }

        // 重复购买， count+1
        specialDealNormalMapper.addCountUserBookInfoTable(userId,bookInfo.getId());


        return true;
    }

    // 在特价专区取消购买
    public boolean noBuy(Integer bookId,Integer userId){
        /*
        * 1.查看用户的的特价表中是否有该book
        * 2.查看count是否大于0
        * 3.用户特价表count-1
        * 4.redis表count+1
        *
        * */

        // 查询用户特价表
        BookInfo bookInfo = specialDealNormalMapper.queryBookInfoByNormalId(bookId,userId);
        if(bookInfo==null || bookInfo.getCount().equals(0)){
            return false;
        }

        // 用户表count-1
        specialDealNormalMapper.deleteSpecialBookCount(bookId,userId);

        // redis count+1
        // 1：获取所有以"bookInfoId:"开头的键
        String keyPattern = "bookInfoId:*";
        Set<String> keys = redisTemplate.keys(keyPattern);

        // 2：遍历键，逐个获取对应的值
        for (String key : keys) {
            BookInfo value = (BookInfo) redisTemplate.opsForValue().get(key);

            //找到购买的book
            if (bookId.equals(value.getId())) {

                // 库存 +1
                value.setCount(value.getCount() + 1);

                //更新到redis
                redisTemplate.opsForValue().set(key, value);

                break;

            }
        }

        return true;
    }

    public PageResult<BookInfo> getSpecialShoppingtrolleyByPage(PageRequest pageRequest,Integer userId) {
        if(pageRequest==null){
            return null;
        }

        //获取表中数据的总数
        Integer count = specialDealNormalMapper.getAllSpecialShoppingtroll(userId);

        //获取该页的数据
        List<BookInfo> bookInfoList = specialDealNormalMapper.getSpecialShoppingtrollbyPage(pageRequest,userId);


        //根据status 修改 statusCN
        for(BookInfo it : bookInfoList){
            // 使用枚举类设置图书的状态
            it.setStatusCN(BookInfoStatusEnum.getNameByCode(it.getStatus()).getName());
        }

        // 创建PageResult对象返回给Controller
        return new PageResult<BookInfo>(count,bookInfoList,pageRequest);

    }
}
